package com.deer.wms.ware.task.web;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deer.wms.base.system.service.ErpService;
import com.deer.wms.intercept.annotation.User;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.constant.InventoryConstant;
import com.deer.wms.inventory.model.Inventory.Inventory;
import com.deer.wms.inventory.model.Inventory.InventoryTransact;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.inventory.service.InventoryTransactService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.system.manage.model.user.UserInfo;
import com.deer.wms.system.manage.service.UserInfoService;
import com.deer.wms.ware.task.model.pushErp.StrategyErpService;
import com.deer.wms.ware.task.model.SO.SoDetail;
import com.deer.wms.ware.task.model.SO.SoMaster;
import com.deer.wms.ware.task.model.Wave.*;
import com.deer.wms.ware.task.model.out.OutDetail;
import com.deer.wms.ware.task.service.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.deer.wms.project.root.core.result.Result;
import com.deer.wms.project.root.core.result.ResultGenerator;
import springfox.documentation.annotations.ApiIgnore;

import java.util.*;

/**
 * @author wei
 * @date 2020/02/02
 */
@RestController
@RequestMapping("/wave/details")
public class WaveDetailController {

    @Autowired
    private WaveDetailService waveDetailService;
    @Autowired
    private WaveMasterService waveMasterService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private SoDetailService soDetailService;
    @Autowired
    private SoMasterService soMasterService;
    @Autowired
    private OutMasterService outMasterService;
    @Autowired
    private InventoryTransactService inventoryTransactService;
    @Autowired
    private StrategyErpService strategyErpService;
    @Autowired
    private ErpService erpService;

    @PostMapping
    public Result add(@RequestBody WaveDetail waveDetail) {
        waveDetailService.save(waveDetail);
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/addFromSo")
    public Result addFromSo(@RequestBody WaveDetailInsertData insertData) {
        WaveMaster wave = waveMasterService.getById(insertData.getWaveMasterId());
        for (Integer soId : insertData.getSoMasterIds()) {
            List<WaveDetailDto> waveDetail1 = waveDetailService.findList(new WaveDetailCriteria(soId));
            if (waveDetail1.size() > 0) {
                return ResultGenerator.genFailResult(CommonCode.SERVER_INERNAL_ERROR, "选中工单中有已添加批次", null);
            }
            WaveDetail waveDetail = new WaveDetail();
            waveDetail.setWaveMasterId(wave.getWaveId());
//            waveDetail.setSoMasterId(soId);
            waveDetailService.save(waveDetail);
        }
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/delete")
    public Result delete(Integer id) {
        waveDetailService.removeById(id);
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/sync/data")
    public Result syncCurrentData(String waveCode) {
        waveDetailService.syncCurrentData(waveCode);
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/update")
    public Result update(@RequestBody WaveDetail waveDetail) {
        waveDetailService.updateById(waveDetail);
        return ResultGenerator.genSuccessResult();
    }

    @Autowired
    private WaveDetailViewService waveDetailViewService;
    @GetMapping("/{id}")
    public Result detail(@PathVariable Integer id, WaveDetailCriteria waveDetailCriteria) {
//        waveDetailCriteria.setWaveId(id);
//        if (ObjectUtil.isNotNull(waveDetailCriteria.getState())) {
//            waveDetailCriteria.setStates(new Integer[]{waveDetailCriteria.getState()});
//        }
//        List<WaveDetailDto> waveDetails = waveDetailService.findList(waveDetailCriteria);
//        for (WaveDetailDto waveDetail : waveDetails) {
//            waveDetail.setInvQty(
//                    WareTaskConstant.WAVE_STATE_PICKING.equals(waveDetail.getState()) || WareTaskConstant.WAVE_STATE_PROCESSING.equals(waveDetail.getState())
//                            ? waveDetail.getInvQty() : null);
//        }
//        // 增加查询先发配件数量的更新
//        waveDetails=waveDetailService.updateXfQuantity(waveDetails);

        List<WaveDetailView> waveDetails = waveDetailViewService.getListByField("wave_master_id", id);

        return ResultGenerator.genSuccessResult(waveDetails);
    }

    @GetMapping
    public Result list(WaveDetailCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<WaveDetailDto> list = waveDetailService.findList(criteria);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/list/pick")
    public Result listForPick(WaveDetailCriteria criteria, @ApiIgnore @User CurrentUser currentUser) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        criteria.setStates(new Integer[]{1, 2});
        criteria.setPickUserId(currentUser.getUserId());

        List<WaveDetailView> state_view = waveDetailViewService.list(new QueryWrapper<WaveDetailView>().eq("state_view", 4));

        PageInfo pageInfo = new PageInfo(state_view);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @PostMapping("/suggest")
    public Result suggestForPick(@RequestBody WaveDetailCriteria waveDetailCriteria, @ApiIgnore @User CurrentUser currentUser) {
        UserInfo wareUser = userInfoService.getById(waveDetailCriteria.getUserId());
        List<String> idsList = Arrays.asList(waveDetailCriteria.getIds().split(","));
        List<WaveDetail> waveDetailList = waveDetailService.listByIds(idsList);

        waveDetailService.suggestForPick(waveDetailList, wareUser, currentUser);
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/sendOut")
    public Result sendOut(String pickIds, Integer wareId,String batchCode, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER);
        }

        String[] split = pickIds.split(",");
        List<Integer> ids = new ArrayList<>();
        for (String s : split) {
            ids.add(Integer.valueOf(s));
        }

        Map<String, String> map = waveDetailService.sendOut(ids, currentUser,wareId,batchCode);
        System.out.println(map);
        return ResultGenerator.genSuccessResult(map);
    }

    /**
     * 先发配件出库
     */
    @PostMapping("/xfPjCk")
    public Result xfPjCk(@RequestBody WaveDetailCriteria waveDetailCriteria, @ApiIgnore @User CurrentUser currentUser) {
        UserInfo wareUser = userInfoService.getById(waveDetailCriteria.getUserId());
        List<String> idsList = Arrays.asList(waveDetailCriteria.getIds().split(","));
        List<WaveDetail> waveDetailList = waveDetailService.listByIds(idsList);

        // 找到相应的出库任务明细 进行验收数量的扣减
        for (WaveDetail waveDetail : waveDetailList) {
            // 1.先查出与波次明细相关的出库明细
            List<SoDetail> soDetails = soDetailService.getListByField("wave_detail_id", waveDetail.getWaveDetailId());
            // 2.找到对应的出库任务(有先发配件库)
            for (SoDetail soDetail : soDetails) {
                SoMaster soMaster = soMasterService.getOneByField("bill_no", soDetail.getBillNo());
                QueryWrapper<Inventory> qw = Wrappers.query();
                Map<String, Object> map = new HashMap<>(4);

                //根据物料批次找到所有对应的库存
                map.put("ware_id", waveDetail.getWareId());
                // 增加筛选条件 库区 484153(先发配件库)
                map.put("erp_area_id", 484153);
                map.put("item_code", waveDetail.getItemCode());
                map.put("batch_name", soMaster.getTradeNo());
                List<Inventory> inventories = inventoryService.getBaseMapper().selectList(qw.allEq(map, true));
                // 如果查出的库存为 0 证明不是先发配件物料
                if (inventories.size() > 0) {
                    // 修改相关明细的拣货完成数量
                    // 记录一下已经分配的数量
                    Double oldQty = soDetail.getAllottedQuantity();
                    // 还需分配的数量
                    Double qty = soDetail.getOrderQuantity() - soDetail.getAllottedQuantity();
                    if (waveDetail.getPreAllottedQuantity() > qty) {
                        //4.找到对应的出库任务明细
                        //5.修改验收数量
                        soDetail.setAllottedQuantity(soDetail.getOrderQuantity());
                        soDetail.setPickQuantity(soDetail.getOrderQuantity());
                        soDetail.setDeliveryQuantity(soDetail.getOrderQuantity());
                        // 将明细的预分配数进行扣减
                        waveDetail.setPreAllottedQuantity(waveDetail.getPreAllottedQuantity()
                                - qty);
                        // 更新出库任务明细信息
                        soDetailService.updateById(soDetail);
                    } else {
                        //4.找到对应的出库任务明细
                        //5.修改验收数量
                        soDetail.setAllottedQuantity(soDetail.getAllottedQuantity()
                                + waveDetail.getPreAllottedQuantity());
                        soDetail.setPickQuantity(soDetail.getAllottedQuantity());
                        soDetail.setDeliveryQuantity(soDetail.getAllottedQuantity());
                        // 将明细的预分配数进行扣减
                        waveDetail.setPreAllottedQuantity(0.0);
                        // 更新出库任务明细信息
                        soDetailService.updateById(soDetail);
                    }
                    // 创建出库单明细--所选择的库存是随机取得一个先发配件库存
                    OutDetail outDetail = new OutDetail(soDetail, inventories.get(0));
                    outDetail.setErpAreaId(484153);
                    // 设置发货数量
                    outDetail.setDeliveryQuantity(soDetail.getAllottedQuantity() - oldQty);
                    // 创建出库单
                    Set<OutDetail> outDetailSet = new HashSet<>();
                    outDetailSet.add(outDetail);
                    String outBill = outMasterService.createOutBill(soMaster, outDetailSet, currentUser);
                    // 出库数量
                    Double quantity = outDetail.getDeliveryQuantity();
                    // 扣减库存
                    for (Inventory inventory : inventories) {
                        // 创建库存事务
                        // 生成库存事务
                        InventoryTransact inventoryTransact = new InventoryTransact();
                        //Step1.准备数据
                        //仓库
                        inventoryTransact.setWareId(inventory.getWareId());
                        inventoryTransact.setWareName(inventory.getWareName());
                        //物料
                        inventoryTransact.setItemCode(inventory.getItemCode());
                        inventoryTransact.setItemName(inventory.getItemName());
                        //批次
                        inventoryTransact.setFromBatchId(inventory.getBatchId());
                        // 履约号--批次
                        inventoryTransact.setFromBatchName(inventory.getBatchName());
                        // 来源库位
                        inventoryTransact.setFromCellCode(inventory.getCellCode());
                        // 创建人 时间
                        inventoryTransact.setCreateUserId(currentUser.getUserId());
                        inventoryTransact.setCreateUserName(currentUser.getUserName());
                        inventoryTransact.setCreateTime(DateUtil.now());
                        //事务类型
                        inventoryTransact.setTransactType(InventoryConstant.INVENTORY_TYPE_OUT);
                        //来源单据号
                        inventoryTransact.setBillNo(outDetail.getDetailNo());
                        // 出库数量--增加判断
                        if (quantity > inventory.getQuantity()) {
                            // 库存不过扣减--先扣减当前数量 继续循环扣减下一个库位的库存
                            inventoryTransact.setFromQuantity(inventory.getQuantity());
                            //Step2.保存，返回
                            inventoryTransactService.save(inventoryTransact);
                            // 执行库存事务 -- 扣减库存
                            inventoryTransactService.run(inventoryTransact);
                            quantity -= inventory.getQuantity();
                        } else {
                            // 库存数量足够扣减
                            inventoryTransact.setFromQuantity(quantity);
                            //Step2.保存，返回
                            inventoryTransactService.save(inventoryTransact);
                            // 执行库存事务 -- 扣减库存
                            inventoryTransactService.run(inventoryTransact);
                            break;
                        }
                    }
                    // 进行ERP数据回传
//                    BaseAssist baseAssist=new BaseAssist();
//                    strategyErpService.resolveSo(soMaster,outDetailSet,baseAssist);
                }
            }
        }
        waveDetailList = waveDetailService.listByIds(idsList);
        // 扣减波次明细数据修改
        for (WaveDetail waveDetail : waveDetailList) {
            //计划数量,用预分配数量扣减
            waveDetail.setQuantity(waveDetail.getQuantity() - waveDetail.getPreAllottedQuantity());
            // 先发配件数量修改
            waveDetail.setXfQuantity(waveDetail.getXfQuantity() - waveDetail.getPreAllottedQuantity());
            // 预分配数量设置为0
            waveDetail.setPreAllottedQuantity(0.0);
            // 更新数据
            waveDetailService.updateById(waveDetail);
        }

        return ResultGenerator.genSuccessResult();
    }

}
